package org.yly.game.rpggame.domain.model.player;

import java.util.Map;
import java.util.Set;

import org.yly.game.rpggame.domain.model.CustomProperty;
import org.yly.game.rpggame.domain.model.DomainEventPublisher;
import org.yly.game.rpggame.domain.model.PropertyName;
import org.yly.game.rpggame.domain.model.PropertyUtils;
import org.yly.game.rpggame.domain.model.TargetType;
import org.yly.game.rpggame.domain.model.UpgradeEntity;
import org.yly.game.rpggame.domain.model.goods.Goods;
import org.yly.game.rpggame.domain.model.pet.Pet;
import org.yly.game.rpggame.domain.model.skill.ActivatedSkill;
import org.yly.game.rpggame.domain.model.skill.Skill;
import org.yly.game.rpggame.domain.model.task.AcceptedTask;
import org.yly.game.rpggame.domain.model.task.Task;

/**
 * 玩家
 * 
 * @author makefu
 * 
 */
public class Player extends UpgradeEntity {

	/* 基本属性 */
	private String name; // 名字
	private int sex; // 性别
	private int money; // 钱
	private Role role; // 角色

	// 物品
	private Map<String, Goods> goodsMap;
	// 技能
	private Map<String, ActivatedSkill> skillMap;

	// 宠物
	private Set<Pet> petSet;
	// 任务
	private Map<String, AcceptedTask> taskMap;
	// 教派Id
	private int sectId;
	//
	private Set<Relation> relationSet;

	public Player(String playerId, Set<CustomProperty> propertySet, Role role, Set<Goods> goodsSet,
			Set<ActivatedSkill> skillSet, Set<Pet> petSet, Set<AcceptedTask> taskSet, int sectId,
			Set<Relation> relationSet) {
		super(playerId, propertySet);
		this.role = role;
		for (Goods goods : goodsSet) {
			this.goodsMap.put(goods.id(), goods);
		}

		for (ActivatedSkill skill : skillSet) {
			this.skillMap.put(skill.getSkill().id(), skill);
		}

		this.petSet = petSet;
		for (AcceptedTask task : taskSet) {
			this.taskMap.put(task.getTask().id(), task);
		}
		this.sectId = sectId;
		this.relationSet = relationSet;
	}

	/**
	 * 获得玩家角色信息
	 * 
	 * @return
	 */
	public Role getRole() {
		return role;
	}

	/**
	 * 获得玩家关系集合
	 * 
	 * @return
	 */
	public Set<Relation> getRelation() {
		return this.relationSet;
	}

	public Goods getGoods(String goodId) {
		return this.goodsMap.get(goodId);
	}

	/**
	 * 添加物品
	 * 
	 * @param goods
	 */
	public void addGoods(Goods goods) {
		this.goodsMap.put(goods.id(), goods);
		goods.getGoodsState().Bind();
	}

	/**
	 * 移除物品
	 * 
	 * @param goods
	 */
	public void removeGoods(String goodId) {
		Goods goods = this.goodsMap.get(goodId);
		if (goods != null) {
			this.goodsMap.remove(goodId);
			goods.getGoodsState().Unbind();
		}
	}

	/**
	 * 使用物品
	 * 
	 * @param goods
	 */
	public void useGoods(String goodsId) {
		Goods goods = this.goodsMap.get(goodsId);
		if (goods != null) {
			goods.getGoodsState().Use();

			// 人物属性=物品属性+人物属性
			PropertyUtils.add(this.getPropertySet(), goods.getPropertySet());
		}

	}

	/**
	 * 卸载物品
	 * 
	 * @param goods
	 */
	public void unuseGoods(String goodsId) {
		Goods goods = this.goodsMap.get(goodsId);
		if (goods != null) {
			goods.getGoodsState().Unuse();

			// 人物属性=人物属性-物品属性
			PropertyUtils.sub(this.getPropertySet(), goods.getPropertySet());
		}

	}

	/**
	 * 锁定物品,不能转移
	 * 
	 * @param goods
	 */
	public void lockGoods(String goodsId) {
		Goods goods = this.goodsMap.get(goodsId);
		if (goods != null) {
			goods.getGoodsState().Lock();
		}
	}

	/**
	 * 销毁物品
	 * 
	 * @param goods
	 */
	public void destroyGoods(String goodsId) {
		Goods goods = this.goodsMap.get(goodsId);
		if (goods != null) {
			goods.getGoodsState().destroy();
		}
	}

	/**
	 * 修理物品
	 * 
	 * @param goodId
	 */
	public void repairGoods(String goodsId) {
		Goods goods = this.goodsMap.get(goodsId);
		if (goods != null) {
			CustomProperty property = goods.getCustomProperty(PropertyName.LossValue);
			if (property != null) {
				property.clearSubValue();
				this.money -= goods.getRepairMoney();
			}
		}
	}

	/**
	 * 添加新的技能
	 * 
	 * @param skill
	 */
	public void addSkill(Skill skill) {
		CustomProperty skillPoint = this.getCustomProperty(PropertyName.SkillPoint);
		if (skillPoint == null) {
			throw new NullPointerException("SkillPoint is null");
		}
		if (skill.isOpen(this.getLevel(), (Integer) (skillPoint.getValue()))) {
			this.skillMap.put(skill.getName(), new ActivatedSkill(skill));
		}
	}

	/**
	 * 移除技能
	 * 
	 * @param skill
	 */
	public void removeSkill(String skillName) {
		this.skillMap.remove(skillName);
	}

	/**
	 * 技能升级
	 * 
	 * @param skill
	 */
	public void upgradeSkill(String skillName) {
		ActivatedSkill skill = this.getSkill(skillName);
		if (skill == null) {
			throw new NullPointerException("skill[" + skillName + "] is null");
		}
		skill.getSkill().upgrade();
	}

	/**
	 * 玩家使用指定技能
	 * 
	 * @param skill
	 * @return
	 */
	public void useSkill(String skillName) {
		ActivatedSkill skill = this.getSkill(skillName);
		if (skill == null) {
			throw new NullPointerException("skill[" + skillName + "] is null");
		}
		PropertyUtils.add(this.getPropertySet(), skill.use(TargetType.Friend));
	}

	/**
	 * 玩家承受指定技能
	 * 
	 * @param skill
	 * @return
	 */
	public void receivedSkill(String skillId) {
		ActivatedSkill skill = this.getSkill(skillId);
		if (skill == null) {
			throw new NullPointerException("skill[" + skillId + "] is null");
		}
		PropertyUtils.add(this.getPropertySet(), skill.use(TargetType.Enemy));
	}

	/**
	 * 获得指定玩家技能
	 * 
	 * @param skillId
	 * @return
	 */
	public ActivatedSkill getSkill(String skillId) {
		return this.skillMap.get(skillId);
	}

	/**
	 * 添加新的任务
	 * 
	 * @param task
	 */
	public void addTask(Task task) {
		if (task.isOpen(this)) {
			this.taskMap.put(task.id(), new AcceptedTask(task));
		}
	}

	/**
	 * 取消已经任务
	 * 
	 * @param task
	 */
	public void cancelTask(String taskId) {
		this.taskMap.remove(taskId);
	}

	/**
	 * 提交任务
	 * @param taskId
	 */
	public void submitTask(String taskId) {
		AcceptedTask task = this.getTask(taskId);
		if (task != null) {
			task.submit();
		} else {
			throw new NullPointerException("task[" + taskId + "] is null");
		}
	}

	/**
	 * 获得指定玩家任务
	 * 
	 * @param skillId
	 * @return
	 */
	public AcceptedTask getTask(String taskId) {
		return this.taskMap.get(taskId);
	}

	/**
	 * 指定任务是否完成
	 * 
	 * @param taskId
	 * @return
	 */
	public boolean completeTask(String taskId) {
		AcceptedTask task = this.getTask(taskId);
		if (task != null) {
			return task.getTaskState().isComplete();
		}
		return false;
	}

	public CustomProperty getProperty(PropertyName name) {
		return this.propertyMap.get(name);
	}

	/**
	 * 添加属性值
	 * 
	 * @param expValue
	 */
	public void addPropertyValue(CustomProperty property) {
		CustomProperty p = this.propertyMap.get(name);
		if (p != null) {
			p.add(property);
		} else {
			throw new NullPointerException("属性不存在[" + name + "]");
		}

		DomainEventPublisher.getInstance().publish(new PlayerPropertyChangeEvent(this.id(), p));
	}

}
